package org.dromara.common.mqtt.callback;


import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.mqtt.domain.CustomMqttClient;
import org.dromara.common.mqtt.enums.CloudApiTopicEnum;
import org.dromara.common.mqtt.handler.MqttMessageHandler;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

/**
 * @Description : MQTT发送客户端的回调类
 * @Author : lsyong
 * @Date : 2023/8/1 16:31
 */
@Slf4j
@Component
public class MqttCallBack implements MqttCallbackExtended {
    @Resource
    private CustomMqttClient customMqttClient;
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 客户端断开后触发
     */
    @Override
    public void connectionLost(Throwable throwable) {
        log.info("连接断开，可以重连");
        if (CustomMqttClient.client == null || !CustomMqttClient.client.isConnected()) {
            log.info("【emqx重新连接】....................................................");
            customMqttClient.reconnection();
        }
    }

    /**
     * 客户端收到消息触发
     *
     * @param topic       主题
     * @param mqttMessage 消息
     */
    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) {
        threadPoolTaskExecutor.execute(() -> {
            try {
                log.info("【接收消息主题】: {}", topic);
                log.info("【接收消息Qos】: {}", mqttMessage.getQos());
                String beanName = CloudApiTopicEnum.getEnumByTopic(topic).getBeanName();
                MqttMessageHandler mqttMessageHandler = SpringUtils.getBean(beanName);
                mqttMessageHandler.handle(extractCodeFromTopic(topic), mqttMessage);
            } catch (Exception e) {
                log.error("消息消费异常{}", topic, e);
            }
        });
    }

    /**
     * 发布消息成功
     *
     * @param token token
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        String[] topics = token.getTopics();
        for (String topic : topics) {
            log.info("向主题【{}】发送消息成功！", topic);
        }
        try {
            MqttMessage message = token.getMessage();
            byte[] payload = message.getPayload();
            String s = new String(payload, StandardCharsets.UTF_8);
            log.info("【消息内容】:{}", s);
        } catch (Exception e) {
            log.error("MqttSendCallBack deliveryComplete error", e);
        }
    }

    /**
     * 连接emq服务器后触发
     *
     * @param b
     * @param s
     */
    @Override
    public void connectComplete(boolean b, String s) {
        log.info("============================= 客户端【{}】连接成功！=============================", CustomMqttClient.client.getClientId());
        // Subscribe to topics
        customMqttClient.subscribe("elevator/status/+", 0);
        customMqttClient.subscribe("elevator/event/+/smoke", 0);
        customMqttClient.subscribe("elevator/event/+/fire", 0);
        customMqttClient.subscribe("elevator/event/+/forbidden_item", 0);
        customMqttClient.subscribe("elevator/event/+/behavior", 0);
        customMqttClient.subscribe("elevator/event/+/person_count", 0);
    }

    private String extractCodeFromTopic(String topic) {
        String[] tokens = topic.split("/");
        return tokens[tokens.length - 2];
    }
}